package com.witsoft.device.controller;


import com.witsoft.device.entity.DeviceEntity;
import com.witsoft.device.entity.DeviceReporterDay;
import com.witsoft.device.entity.DeviceReporterMonth;
import com.witsoft.device.entity.DeviceStatusTimeLineEntity;
import com.witsoft.device.enums.MachineStatusEnum;
import com.witsoft.device.model.DeviceQuota;
import com.witsoft.device.service.DeviceDayReporterService;
import com.witsoft.device.service.DeviceReporterService;
import com.witsoft.device.service.DeviceService;
import com.witsoft.device.service.DeviceStatusTimeLineService;
import com.witsoft.device.utils.DateUtil;
import com.witsoft.device.utils.Result;
import com.witsoft.manager.FeignManager;
import com.witsoft.manager.MessageThreadManager;
import com.witsoft.thingsboard.domain.DeviceStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Api(tags = "设备信息月度报表统计接口", description = "设备信息报表")
@RestController
@RequestMapping("/iot/reporter")
public class DeviceReporterController {

    @Resource
    private DeviceReporterService reporterService;

    @Resource
    private DeviceStatusTimeLineService timeLineService;

    @Resource
    private DeviceService deviceService;

    @Resource
    private DeviceDayReporterService dayReporterService;

    @Resource
    private MessageThreadManager threadPoolManager;

    @Resource
    private FeignManager feignManager;





    /**
     * @desc 所有设备月度时间稼动率
     * @return
     */
    @ApiOperation(value = "时间稼动率折线图")
    @GetMapping("/month/grainMoveRate")
    public Result getMonthReporterGrainMoveRate(){
        //v1
        //Map<String, Object> allDeviceMonthGrainMoveRate = reporterService.getAllDeviceMonthGrainMoveRate();
        //v2 指标计算公式重构
        Map<String, Object> monthGrainMoveRateV2 = reporterService.getAllDeviceMonthGrainMoveRateV2();
        return Result.success(monthGrainMoveRateV2);
    }


    /**
     * @desc 所有设备月度性能稼动率
     * @return
     */
    @ApiOperation(value = "性能稼动率折线图")
    @GetMapping("/month/performanceGrainMoveRate")
    public Result getPerformanceMonthReporterGrainMoveRate(){
        //v1
        //Map<String, Object> allDeviceMonthGrainMoveRate = reporterService.getAllDeviceMonthPerformanceGrainMoveRate();
        //v2 指标计算公式重构
        Map<String, Object> performanceGrainMoveRateV2 = reporterService.getAllDeviceMonthPerformanceGrainMoveRateV2();
        return Result.success(performanceGrainMoveRateV2);
    }



    @GetMapping("/test/message")
    public Result testMessageDispatch(){
        for (int i = 0; i < 200; i++) {
            DeviceStatus deviceStatus = new DeviceStatus();
            deviceStatus.setDeviceName("miki"+i);
            deviceStatus.setCreateDate(new Date());
            threadPoolManager.addMsg(deviceStatus);
        }

        return Result.success("ok");
    }


    @ApiOperation("模拟执行前11个月运行时间报表统计")
    @GetMapping("/test/month-before/execute")
    public Result mockCurrentMonthBeforeReporterExecute() throws ParseException {

        List<DeviceEntity> deviceList = deviceService.getAllList();

        if (!CollectionUtils.isEmpty(deviceList)) {
            for (DeviceEntity deviceEntity : deviceList) {

                List<DeviceReporterMonth> reporterMonths = new ArrayList<>();
                String entityId = deviceEntity.getId();
                for (int i = 1; i <= 11; i++) {
                    DeviceReporterMonth deviceReporterMonth = new DeviceReporterMonth(0L, 0L, DateUtil.sdf_d.parse(DateUtil.getLastDayOfMonth(i)), entityId);
                    deviceReporterMonth.setTimeGrainMoveRate(0.0);
                    deviceReporterMonth.setPerformanceGrainMoveRate(0.0);
                    reporterMonths.add(deviceReporterMonth);
                }

                reporterService.saveBatch(reporterMonths);
            }
        }

        return Result.success("ok");
    }



    @ApiOperation("模拟执行上个月运行时间报表统计")
    @GetMapping("/test/last-month/execute")
    public Result mockLastMonthReporterExecute() {

        List<DeviceEntity> deviceList = deviceService.getAllList();
        List<DeviceReporterMonth> reporterMonths = new ArrayList<>();

        if (!CollectionUtils.isEmpty(deviceList)) {
            for (DeviceEntity deviceEntity : deviceList) {
                //获取上个月的月份格式：2021-12
                String lastMonth = DateUtil.sdf.format(DateUtil.getLastMonth());

                Long sumRunningTimeMonth = timeLineService.getSumRunningTimeLastMonth(deviceEntity.getId());
                Long sumOPenningMonth = timeLineService.getSumOpeningLastMonth(deviceEntity.getId());

                //fixed(2021.11.18): 修复报表统计上个月的数据，时间却是当月的日期的bug
                DeviceReporterMonth deviceReporterMonth = new DeviceReporterMonth(sumRunningTimeMonth, sumOPenningMonth, DateUtil.getLastMonth(), deviceEntity.getId());

                //查询天维度表，统计当月总的稼动率之和
                //性能稼动率
                Double performanceGrainRateMonth = dayReporterService.getSumPerformanceGrainRateMonthById(deviceEntity.getId(), lastMonth);
                deviceReporterMonth.setPerformanceGrainMoveRate(performanceGrainRateMonth);

                //时间稼动率
                Double sumTimeGrainRateMonth = dayReporterService.getSumTimeGrainRateMonthById(deviceEntity.getId(), lastMonth);
                deviceReporterMonth.setTimeGrainMoveRate(sumTimeGrainRateMonth);

                reporterMonths.add(deviceReporterMonth);
            }
        }

        return Result.success(reporterMonths);
    }



    @ApiOperation("模拟执行当月运行时间报表统计")
    @GetMapping("/test/month/execute")
    public Result mockMonthReporterExecute(){

        List<DeviceEntity> deviceList = deviceService.getAllList();
        List<DeviceReporterMonth> reporterMonths = new ArrayList<>();

        if(!CollectionUtils.isEmpty(deviceList)) {

            String currentMonth = DateUtil.sdf.format(new Date());

            for (DeviceEntity deviceEntity : deviceList) {
                Long sumRunningTimeMonth = reporterService.getDeviceSumRunningMonth(deviceEntity.getId());
                Long sumOPenningMonth = reporterService.getDeviceSumOpeningMonth(deviceEntity.getId());

                //fixed(2021.11.18): 修复报表统计上个月的数据，时间却是当月的日期的bug
                DeviceReporterMonth deviceReporterMonth = new DeviceReporterMonth(sumRunningTimeMonth, sumOPenningMonth, DateUtil.getLastMonth(), deviceEntity.getId());

                //查询天维度表，统计当月总的稼动率之和
                //性能稼动率
                Double performanceGrainRateMonth = dayReporterService.getSumPerformanceGrainRateMonthById(deviceEntity.getId(), currentMonth);
                deviceReporterMonth.setPerformanceGrainMoveRate(performanceGrainRateMonth);

                //时间稼动率
                Double sumTimeGrainRateMonth = dayReporterService.getSumTimeGrainRateMonthById(deviceEntity.getId(), currentMonth);
                deviceReporterMonth.setTimeGrainMoveRate(sumTimeGrainRateMonth);

                reporterMonths.add(deviceReporterMonth);
            }
        }

        return Result.success(reporterMonths);
    }



    @ApiOperation("模拟执行上一天运行时间报表统计")
    @GetMapping("/test/day/execute")
    public Result mockDayReporterExecute(){

        Date yesterday = DateUtil.getLastDayOfMonth();
        List<DeviceEntity> deviceList = deviceService.getAllList();
        List<DeviceReporterDay> reporterMonths = new ArrayList<>();

        //TODO 获取mes的所有设备的节拍数和有效产品数乘积
        String deviceCodes = reporterService.getDeviceCodes(deviceList);
        Date start = DateUtil.getCurrentZero(yesterday);
        Map<String, Double> workReportOfDay = deviceService.getBeatMultiplyWorkReportOfDay(deviceCodes, start, yesterday, "day");


        if(!CollectionUtils.isEmpty(deviceList)) {
            String lastMonth = "2021-12";

            for (DeviceEntity deviceEntity : deviceList) {
                //统计前一天的指标，时间稼动率+性能稼动率
                Double beatMulReporterNum = workReportOfDay.get(deviceEntity.getName());
                Long openingTimeByDayTime = timeLineService.getSumOpenningTimeByDayTime(deviceEntity.getId(), DateUtil.sdf_d.format(DateUtil.getLastDay()));
                Long runningTimeByDayTime = timeLineService.getSumRunningTimeByDayTime(deviceEntity.getId(), DateUtil.sdf_d.format(DateUtil.getLastDay()));

                //fixed(2021.12.03):
                DeviceReporterDay deviceReporterDay = new DeviceReporterDay(runningTimeByDayTime, openingTimeByDayTime, yesterday, deviceEntity.getId());

                //设置昨日生产数
                deviceReporterDay.setNumberOfProducts(5000l);

                Double rate = 0.0, timeRate = 0.0;
                //计算性能稼动率
                if(runningTimeByDayTime > 0){
                    rate = beatMulReporterNum / runningTimeByDayTime;
                }
                deviceReporterDay.setPerformanceGrainMoveRate(100 * rate);

                if(openingTimeByDayTime > 0){
                    timeRate = 1.0 * runningTimeByDayTime / openingTimeByDayTime;
                }
                deviceReporterDay.setTimeGrainMoveRate(100 * timeRate);

                reporterMonths.add(deviceReporterDay);
            }
        }

        dayReporterService.saveBatch(reporterMonths);
        return Result.success(reporterMonths);
    }



    /**
     * 计算指标测试接口
     * @param deviceId
     * @return
     */
    @ApiOperation(value = "单个设备指标计算")
    @GetMapping("/test/getAverageDeviceTarget")
    public Result getDeviceAverageInfo(String deviceId){

        Double quantityRate = 0d, performanceRate = 0.0, availability = 0.0;
        DecimalFormat df = new DecimalFormat("#");

        DeviceEntity deviceEntity = deviceService.getInfo(deviceId);

        DeviceQuota deviceQuota = new DeviceQuota();
        Long totalCount = deviceEntity.getTotalCount();

        //feature(2022.01.13): 计算今日生产总数， -->设备表存的是设备当年总的生产数
        //获取该设备的今日不合格数
        Map<String, String> badCountMap = feignManager.getBadProductCountByDevice(deviceEntity.getName());
        //截止昨天，该设备的生产总数
        Long lastDayProductTotal = dayReporterService.getLastDayProductTotal(deviceId);
        if(!ObjectUtils.isEmpty(lastDayProductTotal) && lastDayProductTotal < totalCount){
            //今日生产总数
            totalCount = totalCount - lastDayProductTotal;
        }


        //合格率计算： 合格数量/总数量
        deviceQuota.setQuantity("0");
        if(totalCount > 0){
            //今日不合格数
            Long badCount = 0l;
            String badNumber = badCountMap.get(deviceEntity.getName());
            if(!ObjectUtils.isEmpty(badNumber)){
                badCount = Long.parseLong(badNumber);
            }

            quantityRate = 1.0 * (totalCount - badCount) / totalCount;
            deviceQuota.setQuantity(df.format(quantityRate * 100));
        }


        //性能开动率计算：
        //取当前设备当天的所有运行时长(单位：秒)
        int sumRunning = timeLineService.getSumRunningTimeDay(deviceEntity.getId());
        if(totalCount > 0 && sumRunning > 0){
            performanceRate = (1.0 * 2) / (1.0 * sumRunning/deviceEntity.getTotalCount());
        }
        deviceQuota.setPerformance(df.format(performanceRate * 100));


        //时间开动率计算：
        //取当前设备当天的所有记录时长(单位：秒)
        int sumTime = timeLineService.getSumTime(deviceEntity.getId());
        availability = sumTime <= 0 ? 0 : (1.0*sumRunning)/sumTime;
        deviceQuota.setAvailability(df.format(availability * 100));


        //oee计算：
        Double oeeRate = quantityRate * performanceRate * availability;
        deviceQuota.setOee(df.format(oeeRate * 100));

        return Result.success(deviceQuota);
    }


    @PostMapping("/month/test/save")
    public Result saveReporter(){

        Long sumRunningTimeMonth = timeLineService.getSumRunningTimeLastMonth("4");
        DeviceReporterMonth deviceReporterMonth = new DeviceReporterMonth();
        deviceReporterMonth.setCreateTime(new Date());
        deviceReporterMonth.setDeviceId("4");
        deviceReporterMonth.setTimeGrainMoveRate(sumRunningTimeMonth.doubleValue());

        boolean save = reporterService.save(deviceReporterMonth);

        return Result.success(save);
    }


    @PostMapping("/month/test/update")
    public Result update(String deviceId){

        //获取今天最近的一次开机事件记录
        DeviceStatusTimeLineEntity lastOneTURNING = timeLineService.getLastOneInfoByStatus(deviceId, MachineStatusEnum.TURNING.getCodeStr());
        if(!ObjectUtils.isEmpty(lastOneTURNING)) {
            //计算时间差
            Long leftSeconds = DateUtil.getLeftSeconds(lastOneTURNING.getStartTime(), new Date());
            lastOneTURNING.setTotalSpent(leftSeconds);

            //fixed（修复时序图展示缺失问题需要结束时间）：完善时序图结束时间  2021.11.10
            lastOneTURNING.setEndTime(new Date());
            lastOneTURNING.setEventTime(new Date());

            //更新差值
            timeLineService.saveOrUpdate(lastOneTURNING);
        }
        return Result.success(true);
    }
}
